/*
 * UDPListener.cpp
 *
 *  Created on: 18.03.2011
 *      Author: niea
 */


#include "UDPListener.hpp"
#include "../common/Utils.hpp"
#include "../common/ClientEntry.hpp"
#include "../common/ClientEntryList.hpp"
#include "../common/MyIP.hpp"

#include <cstring>

using namespace efs;

UDPListener::UDPListener(Settings const& settings, ClientEntryList *client_list)
	: UDPThread(settings)
	, m_client_list(client_list)
{
}

void UDPListener::threadProc()
{
	listenPing();
}

void UDPListener::listenPing()
{
	int len = 1;
	setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, &len, sizeof(len));

	struct sockaddr_in sockaddr;
	memset(&m_sockaddr, 0, sizeof(sockaddr));
	sockaddr.sin_family = AF_INET;
	sockaddr.sin_port = htons (m_settings.udp_port);
	sockaddr.sin_addr.s_addr = htonl(0xFFFFFFFF);

	while (1)
	{
		fd_set readset;
		FD_ZERO (&readset);
		FD_SET (m_socket, &readset);

		// set the timeout
		timeval timeout;
		timeout.tv_sec = 0;//1;//m_wait_timeout; //TODO: param
		timeout.tv_usec = 10 * 1000;

		if (m_stop_req)
		{
			pantheios::log_DEBUG("[UPDListener]: Exit on user command");
			closeAll();
			return;
		}

		// waiting for event in socket
		if (select(m_socket + 1, &readset, NULL, NULL, &timeout) <= 0)
		{
			//m_stop_req = true;
			continue;
		}

		const int BUFFSIZE = 255;
		char buffer[BUFFSIZE];
		int received;
		socklen_t clientlen = sizeof(sockaddr);
		if (received = recvfrom(m_socket, buffer, BUFFSIZE, 0,
				(struct sockaddr *) &sockaddr, &clientlen) < 0)
		{
			pantheios::log_ERROR("[UPDListener]: Failed to receive message");
		}

		ClientEntry client_entry;

		//pantheios::log_DEBUG("[UPDListener]: rcv");
		if(client_entry.putXMLString(buffer))
		{
			//my_client_entry.m_ip = my_ip.getMyIP();
			if (!(m_settings.my_net_settings == client_entry))
			{
				if (m_client_list->addEntry(client_entry))
				{
					m_client_list->print();
				}
			}
		}
	}
}
